<?php
/**
 * RendererAbstract.php
 *
 * @author		b.wenneker <b.wenneker@gmail.com>, 2010
 */
abstract class Application_Form_Renderer_RendererAbstract
{
	
	/**
	 * Form to be rendered.
	 *
	 * @author b.wenneker <b.wenneker@gmail.com>, 2010
	 * @var Application_Form_FormAbstract $_form
	 */
	protected $_form = null;
	
	/**
	 * Whether or not this is a subform.
	 *
	 * @author b.wenneker <b.wenneker@gmail.com>, 2010
	 * @var bool $_isSubForm
	 */
	protected $_isSubForm = false;
	
	/**
	 * Will be set to true if setup has completed before rendering.
	 *
	 * @author b.wenneker <b.wenneker@gmail.com>, 2010
	 * @var boolean $_isSetup
	 */
	protected $_isSetup = false;
	
	/**
	 *
	 * @author b.wenneker <b.wenneker@gmail.com>, 2010
	 * @param Application_Form_FormAbstract $form
	 */
	public function __construct (Application_Form_FormAbstract $form, $isSubForm = false)
	{
		
		$this->_form 		= $form;
		$this->_isSubForm 	= $isSubForm;
	}
	
	/**
	 * Can be called before calling render() to provide a window where
	 * element properties can be changed before the actual rendering.
	 *
	 * @author b.wenneker <b.wenneker@gmail.com>, 2010
	 */
	final public function setupRender()
	{
		
		// Propagate setup down the chain to subforms.
		$rendererClass 			= get_class($this);
		
		// Loop over subforms of the form.
		foreach ($this->_form->getSubForms() as $subForm) {
			$subFormRenderer 	= new $rendererClass($subForm, true);
			$subFormRenderer	->setupRender();
		}

		if (!$this->_isSetup) {
			// Setup when the form wasn't set up yet.
			$this->_setupRender();
		}
		$this->_isSetup 		= true;
	}

	/**
	 * Setup method (was: render) that needs to be implemented
	 *
	 * @author b.wenneker <b.wenneker@gmail.com>, 2010
	 */
	abstract protected function _setupRender();

	/**
	 * _setupSingleElement() - Sets up the form for a single element.
	 *
	 * @author b.wenneker <b.wenneker@gmail.com>, 2010
	 * @param Zend_Form_Element $element Element to setup.
	 */
	protected function _setupSingleElement (Zend_Form_Element $element)
	{
	
		if ($element instanceof Application_Form_Element_Label) {
			$element->removeDecorator('ViewHelper');
			$element->addDecorator(new Application_Form_Decorator_Label());
		}
	}
	
	/**
	 * Render method that needs to be implemented
	 *
	 * @author [tb] t.beijen <t.beijen@solware.nl>, 28 jan 2010
	 * @return string
	 */
	public function render() {
		if (!$this->_isSetup) {
			// Setup when the form wasn't set up yet.
			$this->setupRender();
		}
		$this->_isSetup 		= true;

		return $this->_form->render();
	}
	
//	/**
//	 * Call the render function on all items that reside in the renderList.
//	 *
//	 * @author b.wenneker <b.wenneker@gmail.com>, 2010
//	 * @return string Html string of the rendered form.
//	 */
//	public function render ()
//	{
//		$this					->_setupRender();
//		$renderedItems			= '';
//
//		$forms 					= $this->getForms();
//		foreach ($forms as $form) {
//
//			$renderedItems 		.= $form->render();
//
//			if (false === $form->getIsSubForm()) {
//				$renderedItems 	.= $this->addSubmit();
//			}
//		}
//
//		return $renderedItems;
//	}
	
	/**
	 * Called when this object is casted to a string, this function will function as a hubcall to the render() function.
	 *
	 * @return string
	 */
	public function __toString ()
	{
		return $this->render();
	}
	
	/**
	 * Function which is called before rendering to manipulate the rendering (in subclasses this is the function to manipulate rendering properties).
	 */
//	protected function _setupRender ()
//	{}
}